;( function(window, $, undefined) { ; ( function() { var VERSION = '2.2.3', pluginName = 'wpcdpk', autoInitSelector = '.wpcdpk-here', $body, $wpcdpksContainer, containerBuilt = false, baseTemplate = '' + '
' + '' + '' + '
' + '
', defaults = { classes: '', inline: false, language: 'en', startDate: new Date(), firstDay: '', weekends: [6, 0], dateFormat: '', altField: '', altFieldDateFormat: '@', toggleSelected: true, keyboardNav: true, position: 'bottom left', offset: 12, view: 'days', minView: 'days', showOtherMonths: true, selectOtherMonths: true, moveToOtherMonthsOnSelect: true, showOtherYears: true, selectOtherYears: true, moveToOtherYearsOnSelect: true, minDate: '', maxDate: '', disableNavWhenOutOfRange: true, multipleDates: false, // Boolean or Number multipleDatesSeparator: ',', range: false, todayButton: false, clearButton: false, showEvent: 'focus', autoClose: false, // navigation monthsField: 'monthsShort', prevHtml: '', nextHtml: '', navTitles: { days: 'MM, yyyy', months: 'yyyy', years: 'yyyy1 - yyyy2', }, // timepicker timepicker: false, onlyTimepicker: false, dateTimeSeparator: ' ', timeFormat: '', minHours: 0, maxHours: 24, minMinutes: 0, maxMinutes: 59, hoursStep: 1, minutesStep: 1, // events onSelect: '', onShow: '', onHide: '', onChangeMonth: '', onChangeYear: '', onChangeDecade: '', onChangeView: '', onRenderCell: '', }, hotKeys = { 'ctrlRight': [17, 39], 'ctrlUp': [17, 38], 'ctrlLeft': [17, 37], 'ctrlDown': [17, 40], 'shiftRight': [16, 39], 'shiftUp': [16, 38], 'shiftLeft': [16, 37], 'shiftDown': [16, 40], 'altUp': [18, 38], 'altRight': [18, 39], 'altLeft': [18, 37], 'altDown': [18, 40], 'ctrlShiftUp': [16, 17, 38], }, wpcdpk; var Wpcdpk = function(el, options) { this.el = el; this.$el = $(el); this.opts = $.extend(true, {}, defaults, options, this.$el.data()); if ($body == undefined) { $body = $('body'); } if (!this.opts.startDate) { this.opts.startDate = new Date(); } if (this.el.nodeName == 'INPUT') { this.elIsInput = true; } if (this.opts.altField) { this.$altField = typeof this.opts.altField == 'string' ? $(this.opts.altField) : this.opts.altField; } this.inited = false; this.visible = false; this.silent = false; // Need to prevent unnecessary rendering this.currentDate = this.opts.startDate; this.currentView = this.opts.view; this._createShortCuts(); this.selectedDates = []; this.views = {}; this.keys = []; this.minRange = ''; this.maxRange = ''; this._prevOnSelectValue = ''; this.init(); }; wpcdpk = Wpcdpk; wpcdpk.prototype = { VERSION: VERSION, viewIndexes: ['days', 'months', 'years'], init: function() { if (!containerBuilt && !this.opts.inline && this.elIsInput) { this._buildWpcdpksContainer(); } this._buildBaseHtml(); this._defineLocale(this.opts.language); this._syncWithMinMaxDates(); if (this.elIsInput) { if (!this.opts.inline) { // Set extra classes for proper transitions this._setPositionClasses(this.opts.position); this._bindEvents(); } if (this.opts.keyboardNav && !this.opts.onlyTimepicker) { this._bindKeyboardEvents(); } this.$wpcdpk.on('mousedown', this._onMouseDownWpcdpk.bind(this)); this.$wpcdpk.on('mouseup', this._onMouseUpWpcdpk.bind(this)); } if (this.opts.classes) { this.$wpcdpk.addClass(this.opts.classes); } if (this.opts.timepicker) { this.timepicker = new $.fn.wpcdpk.Timepicker(this, this.opts); this._bindTimepickerEvents(); } if (this.opts.onlyTimepicker) { this.$wpcdpk.addClass('-only-timepicker-'); } this.views[this.currentView] = new $.fn.wpcdpk.Body(this, this.currentView, this.opts); this.views[this.currentView].show(); this.nav = new $.fn.wpcdpk.Navigation(this, this.opts); this.view = this.currentView; this.$el.on('clickCell.adp', this._onClickCell.bind(this)); this.$wpcdpk.on('mouseenter', '.wpcdpk--cell', this._onMouseEnterCell.bind(this)); this.$wpcdpk.on('mouseleave', '.wpcdpk--cell', this._onMouseLeaveCell.bind(this)); this.inited = true; }, _createShortCuts: function() { this.minDate = this.opts.minDate ? this.opts.minDate : new Date(-8639999913600000); this.maxDate = this.opts.maxDate ? this.opts.maxDate : new Date(8639999913600000); }, _bindEvents: function() { this.$el.on(this.opts.showEvent + '.adp', this._onShowEvent.bind(this)); this.$el.on('mouseup.adp', this._onMouseUpEl.bind(this)); this.$el.on('blur.adp', this._onBlur.bind(this)); this.$el.on('keyup.adp', this._onKeyUpGeneral.bind(this)); $(window).on('resize.adp', this._onResize.bind(this)); $('body').on('mouseup.adp', this._onMouseUpBody.bind(this)); }, _bindKeyboardEvents: function() { this.$el.on('keydown.adp', this._onKeyDown.bind(this)); this.$el.on('keyup.adp', this._onKeyUp.bind(this)); this.$el.on('hotKey.adp', this._onHotKey.bind(this)); }, _bindTimepickerEvents: function() { this.$el.on('timeChange.adp', this._onTimeChange.bind(this)); }, isWeekend: function(day) { return this.opts.weekends.indexOf(day) !== -1; }, _defineLocale: function(lang) { if (typeof lang == 'string') { this.loc = $.fn.wpcdpk.language[lang]; if (!this.loc) { console.warn('Can\'t find language "' + lang + '" in Wpcdpk.language, will use "ru" instead'); this.loc = $.extend(true, {}, $.fn.wpcdpk.language.ru); } this.loc = $.extend(true, {}, $.fn.wpcdpk.language.ru, $.fn.wpcdpk.language[lang]); } else { this.loc = $.extend(true, {}, $.fn.wpcdpk.language.ru, lang); } if (this.opts.dateFormat) { this.loc.dateFormat = this.opts.dateFormat; } if (this.opts.timeFormat) { this.loc.timeFormat = this.opts.timeFormat; } if (this.opts.firstDay !== '') { this.loc.firstDay = this.opts.firstDay; } if (this.opts.timepicker) { this.loc.dateFormat = [ this.loc.dateFormat, this.loc.timeFormat, ].join(this.opts.dateTimeSeparator); } if (this.opts.onlyTimepicker) { this.loc.dateFormat = this.loc.timeFormat; } var boundary = this._getWordBoundaryRegExp; if (this.loc.timeFormat.match(boundary('aa')) || this.loc.timeFormat.match(boundary('AA')) ) { this.ampm = true; } }, _buildWpcdpksContainer: function() { containerBuilt = true; $body.append( '
'); $wpcdpksContainer = $('#wpcdpks-container'); }, _buildBaseHtml: function() { var $appendTarget, $inline = $('
'); if (this.el.nodeName == 'INPUT') { if (!this.opts.inline) { $appendTarget = $wpcdpksContainer; } else { $appendTarget = $inline.insertAfter(this.$el); } } else { $appendTarget = $inline.appendTo(this.$el); } this.$wpcdpk = $(baseTemplate).appendTo($appendTarget); this.$content = $('.wpcdpk--content', this.$wpcdpk); this.$nav = $('.wpcdpk--nav', this.$wpcdpk); }, _triggerOnChange: function() { if (!this.selectedDates.length) { // Prevent from triggering multiple onSelect callback with same argument (empty string) in IE10-11 if (this._prevOnSelectValue === '') { return; } this._prevOnSelectValue = ''; return this.opts.onSelect('', '', this); } var selectedDates = this.selectedDates, parsedSelected = wpcdpk.getParsedDate(selectedDates[0]), formattedDates, _this = this, dates = new Date( parsedSelected.year, parsedSelected.month, parsedSelected.date, parsedSelected.hours, parsedSelected.minutes, ); formattedDates = selectedDates.map(function(date) { return _this.formatDate(_this.loc.dateFormat, date); }).join(this.opts.multipleDatesSeparator); // Create new dates array, to separate it from original selectedDates if (this.opts.multipleDates || this.opts.range) { dates = selectedDates.map(function(date) { var parsedDate = wpcdpk.getParsedDate(date); return new Date( parsedDate.year, parsedDate.month, parsedDate.date, parsedDate.hours, parsedDate.minutes, ); }); } this._prevOnSelectValue = formattedDates; this.opts.onSelect(formattedDates, dates, this); }, next: function() { var d = this.parsedDate, o = this.opts; switch (this.view) { case 'days': this.date = new Date(d.year, d.month + 1, 1); if (o.onChangeMonth) { o.onChangeMonth(this.parsedDate.month, this.parsedDate.year); } break; case 'months': this.date = new Date(d.year + 1, d.month, 1); if (o.onChangeYear) { o.onChangeYear(this.parsedDate.year); } break; case 'years': this.date = new Date(d.year + 10, 0, 1); if (o.onChangeDecade) { o.onChangeDecade(this.curDecade); } break; } }, prev: function() { var d = this.parsedDate, o = this.opts; switch (this.view) { case 'days': this.date = new Date(d.year, d.month - 1, 1); if (o.onChangeMonth) { o.onChangeMonth(this.parsedDate.month, this.parsedDate.year); } break; case 'months': this.date = new Date(d.year - 1, d.month, 1); if (o.onChangeYear) { o.onChangeYear(this.parsedDate.year); } break; case 'years': this.date = new Date(d.year - 10, 0, 1); if (o.onChangeDecade) { o.onChangeDecade(this.curDecade); } break; } }, formatDate: function(string, date) { date = date || this.date; var result = string, boundary = this._getWordBoundaryRegExp, locale = this.loc, leadingZero = wpcdpk.getLeadingZeroNum, decade = wpcdpk.getDecade(date), d = wpcdpk.getParsedDate(date), fullHours = d.fullHours, hours = d.hours, ampm = string.match(boundary('aa')) || string.match(boundary('AA')), dayPeriod = 'am', replacer = this._replacer, validHours; if (this.opts.timepicker && this.timepicker && ampm) { validHours = this.timepicker._getValidHoursFromDate(date, ampm); fullHours = leadingZero(validHours.hours); hours = validHours.hours; dayPeriod = validHours.dayPeriod; } switch (true) { case /@/.test(result): result = result.replace(/@/, date.getTime()); case /aa/.test(result): result = replacer(result, boundary('aa'), dayPeriod); case /AA/.test(result): result = replacer(result, boundary('AA'), dayPeriod.toUpperCase()); case /dd/.test(result): result = replacer(result, boundary('dd'), d.fullDate); case /d/.test(result): result = replacer(result, boundary('d'), d.date); case /DD/.test(result): result = replacer(result, boundary('DD'), locale.days[d.day]); case /D/.test(result): result = replacer(result, boundary('D'), locale.daysShort[d.day]); case /mm/.test(result): result = replacer(result, boundary('mm'), d.fullMonth); case /m/.test(result): result = replacer(result, boundary('m'), d.month + 1); case /MM/.test(result): result = replacer(result, boundary('MM'), this.loc.months[d.month]); case /M/.test(result): result = replacer(result, boundary('M'), locale.monthsShort[d.month]); case /ii/.test(result): result = replacer(result, boundary('ii'), d.fullMinutes); case /i/.test(result): result = replacer(result, boundary('i'), d.minutes); case /hh/.test(result): result = replacer(result, boundary('hh'), fullHours); case /h/.test(result): result = replacer(result, boundary('h'), hours); case /yyyy/.test(result): result = replacer(result, boundary('yyyy'), d.year); case /yyyy1/.test(result): result = replacer(result, boundary('yyyy1'), decade[0]); case /yyyy2/.test(result): result = replacer(result, boundary('yyyy2'), decade[1]); case /yy/.test(result): result = replacer(result, boundary('yy'), d.year.toString().slice(-2)); } return result; }, _replacer: function(str, reg, data) { return str.replace(reg, function(match, p1, p2, p3) { return p1 + data + p3; }); }, _getWordBoundaryRegExp: function(sign) { var symbols = '\\s|\\.|-|/|\\\\|,|\\$|\\!|\\?|:|;'; return new RegExp( '(^|>|' + symbols + ')(' + sign + ')($|<|' + symbols + ')', 'g'); }, selectDate: function(date) { var _this = this, opts = _this.opts, d = _this.parsedDate, selectedDates = _this.selectedDates, len = selectedDates.length, newDate = ''; if (Array.isArray(date)) { date.forEach(function(d) { _this.selectDate(d); }); return; } if (!( date instanceof Date )) { return; } this.lastSelectedDate = date; // Set new time values from Date if (this.timepicker) { this.timepicker._setTime(date); } // On this step timepicker will set valid values in it's instance _this._trigger('selectDate', date); // Set correct time values after timepicker's validation // Prevent from setting hours or minutes which values are lesser then `min` value or // greater then `max` value if (this.timepicker) { date.setHours(this.timepicker.hours); date.setMinutes(this.timepicker.minutes); } if (_this.view == 'days') { if (date.getMonth() != d.month && opts.moveToOtherMonthsOnSelect) { newDate = new Date(date.getFullYear(), date.getMonth(), 1); } } if (_this.view == 'years') { if (date.getFullYear() != d.year && opts.moveToOtherYearsOnSelect) { newDate = new Date(date.getFullYear(), 0, 1); } } if (newDate) { _this.silent = true; _this.date = newDate; _this.silent = false; _this.nav._render(); } if (opts.multipleDates && !opts.range) { // Set priority to range functionality if (len === opts.multipleDates) { return; } if (!_this._isSelected(date)) { _this.selectedDates.push(date); } } else if (opts.range) { if (len == 2) { _this.selectedDates = [date]; _this.minRange = date; _this.maxRange = ''; } else if (len == 1) { _this.selectedDates.push(date); if (!_this.maxRange) { _this.maxRange = date; } else { _this.minRange = date; } // Swap dates if they were selected via dp.selectDate() and second date was smaller then first if (wpcdpk.bigger(_this.maxRange, _this.minRange)) { _this.maxRange = _this.minRange; _this.minRange = date; } _this.selectedDates = [_this.minRange, _this.maxRange]; } else { _this.selectedDates = [date]; _this.minRange = date; } } else { _this.selectedDates = [date]; } _this._setInputValue(); if (opts.onSelect) { _this._triggerOnChange(); } if (opts.autoClose && !this.timepickerIsActive) { if (!opts.multipleDates && !opts.range) { _this.hide(); } else if (opts.range && _this.selectedDates.length == 2) { _this.hide(); } } _this.views[this.currentView]._render(); }, removeDate: function(date) { var selected = this.selectedDates, _this = this; if (!( date instanceof Date )) { return; } return selected.some(function(curDate, i) { if (wpcdpk.isSame(curDate, date)) { selected.splice(i, 1); if (!_this.selectedDates.length) { _this.minRange = ''; _this.maxRange = ''; _this.lastSelectedDate = ''; } else { _this.lastSelectedDate = _this.selectedDates[_this.selectedDates.length - 1]; } _this.views[_this.currentView]._render(); _this._setInputValue(); if (_this.opts.onSelect) { _this._triggerOnChange(); } return true; } }); }, today: function() { this.silent = true; this.view = this.opts.minView; this.silent = false; this.date = new Date(); if (this.opts.todayButton instanceof Date) { this.selectDate(this.opts.todayButton); } }, clear: function() { this.selectedDates = []; this.minRange = ''; this.maxRange = ''; this.views[this.currentView]._render(); this._setInputValue(); if (this.opts.onSelect) { this._triggerOnChange(); } }, /** * Updates wpcdpk options * @param {String|Object} param - parameter's name to update. If object then it will extend current options * @param {String|Number|Object} [value] - new param value */ update: function(param, value) { var len = arguments.length, lastSelectedDate = this.lastSelectedDate; if (len == 2) { this.opts[param] = value; } else if (len == 1 && typeof param == 'object') { this.opts = $.extend(true, this.opts, param); } this._createShortCuts(); this._syncWithMinMaxDates(); this._defineLocale(this.opts.language); this.nav._addButtonsIfNeed(); if (!this.opts.onlyTimepicker) { this.nav._render(); } this.views[this.currentView]._render(); if (this.elIsInput && !this.opts.inline) { this._setPositionClasses(this.opts.position); if (this.visible) { this.setPosition(this.opts.position); } } if (this.opts.classes) { this.$wpcdpk.addClass(this.opts.classes); } if (this.opts.onlyTimepicker) { this.$wpcdpk.addClass('-only-timepicker-'); } if (this.opts.timepicker) { if (lastSelectedDate) { this.timepicker._handleDate(lastSelectedDate); } this.timepicker._updateRanges(); this.timepicker._updateCurrentTime(); // Change hours and minutes if it's values have been changed through min/max hours/minutes if (lastSelectedDate) { lastSelectedDate.setHours(this.timepicker.hours); lastSelectedDate.setMinutes(this.timepicker.minutes); } } this._setInputValue(); return this; }, _syncWithMinMaxDates: function() { var curTime = this.date.getTime(); this.silent = true; if (this.minTime > curTime) { this.date = this.minDate; } if (this.maxTime < curTime) { this.date = this.maxDate; } this.silent = false; }, _isSelected: function(checkDate, cellType) { var res = false; this.selectedDates.some(function(date) { if (wpcdpk.isSame(date, checkDate, cellType)) { res = date; return true; } }); return res; }, _setInputValue: function() { var _this = this, opts = _this.opts, format = _this.loc.dateFormat, altFormat = opts.altFieldDateFormat, value = _this.selectedDates.map(function(date) { return _this.formatDate(format, date); }), altValues; if (opts.altField && _this.$altField.length) { altValues = this.selectedDates.map(function(date) { return _this.formatDate(altFormat, date); }); altValues = altValues.join(this.opts.multipleDatesSeparator); this.$altField.val(altValues); } value = value.join(this.opts.multipleDatesSeparator); this.$el.val(value); }, /** * Check if date is between minDate and maxDate * @param date {object} - date object * @param type {string} - cell type * @returns {boolean} * @private */ _isInRange: function(date, type) { var time = date.getTime(), d = wpcdpk.getParsedDate(date), min = wpcdpk.getParsedDate(this.minDate), max = wpcdpk.getParsedDate(this.maxDate), dMinTime = new Date(d.year, d.month, min.date).getTime(), dMaxTime = new Date(d.year, d.month, max.date).getTime(), types = { day: time >= this.minTime && time <= this.maxTime, month: dMinTime >= this.minTime && dMaxTime <= this.maxTime, year: d.year >= min.year && d.year <= max.year, }; return type ? types[type] : types.day; }, _getDimensions: function($el) { var offset = $el.offset(); return { width: $el.outerWidth(), height: $el.outerHeight(), left: offset.left, top: offset.top, }; }, _getDateFromCell: function(cell) { var curDate = this.parsedDate, year = cell.data('year') || curDate.year, month = cell.data('month') == undefined ? curDate.month : cell.data('month'), date = cell.data('date') || 1; return new Date(year, month, date); }, _setPositionClasses: function(pos) { pos = pos.split(' '); var main = pos[0], sec = pos[1], classes = 'wpcdpk -' + main + '-' + sec + '- -from-' + main + '-'; if (this.visible) { classes += ' active'; } this.$wpcdpk.removeAttr('class').addClass(classes); }, setPosition: function(position) { position = position || this.opts.position; var dims = this._getDimensions(this.$el), selfDims = this._getDimensions(this.$wpcdpk), pos = position.split(' '), top, left, offset = this.opts.offset, main = pos[0], secondary = pos[1]; switch (main) { case 'top': top = dims.top - selfDims.height - offset; break; case 'right': left = dims.left + dims.width + offset; break; case 'bottom': top = dims.top + dims.height + offset; break; case 'left': left = dims.left - selfDims.width - offset; break; } switch (secondary) { case 'top': top = dims.top; break; case 'right': left = dims.left + dims.width - selfDims.width; break; case 'bottom': top = dims.top + dims.height - selfDims.height; break; case 'left': left = dims.left; break; case 'center': if (/left|right/.test(main)) { top = dims.top + dims.height / 2 - selfDims.height / 2; } else { left = dims.left + dims.width / 2 - selfDims.width / 2; } } this.$wpcdpk.css({ left: left, top: top, }); }, show: function() { var onShow = this.opts.onShow; this.setPosition(this.opts.position); this.$wpcdpk.addClass('active'); this.visible = true; if (onShow) { this._bindVisionEvents(onShow); } }, hide: function() { var onHide = this.opts.onHide; this.$wpcdpk.removeClass('active').css({ left: '-100000px', }); this.focused = ''; this.keys = []; this.inFocus = false; this.visible = false; this.$el.blur(); if (onHide) { this._bindVisionEvents(onHide); } }, down: function(date) { this._changeView(date, 'down'); }, up: function(date) { this._changeView(date, 'up'); }, _bindVisionEvents: function(event) { this.$wpcdpk.off('transitionend.dp'); event(this, false); this.$wpcdpk.one('transitionend.dp', event.bind(this, this, true)); }, _changeView: function(date, dir) { date = date || this.focused || this.date; var nextView = dir == 'up' ? this.viewIndex + 1 : this.viewIndex - 1; if (nextView > 2) { nextView = 2; } if (nextView < 0) { nextView = 0; } this.silent = true; this.date = new Date(date.getFullYear(), date.getMonth(), 1); this.silent = false; this.view = this.viewIndexes[nextView]; }, _handleHotKey: function(key) { var date = wpcdpk.getParsedDate(this._getFocusedDate()), focusedParsed, o = this.opts, newDate, totalDaysInNextMonth, monthChanged = false, yearChanged = false, decadeChanged = false, y = date.year, m = date.month, d = date.date; switch (key) { case 'ctrlRight': case 'ctrlUp': m += 1; monthChanged = true; break; case 'ctrlLeft': case 'ctrlDown': m -= 1; monthChanged = true; break; case 'shiftRight': case 'shiftUp': yearChanged = true; y += 1; break; case 'shiftLeft': case 'shiftDown': yearChanged = true; y -= 1; break; case 'altRight': case 'altUp': decadeChanged = true; y += 10; break; case 'altLeft': case 'altDown': decadeChanged = true; y -= 10; break; case 'ctrlShiftUp': this.up(); break; } totalDaysInNextMonth = wpcdpk.getDaysCount(new Date(y, m)); newDate = new Date(y, m, d); // If next month has less days than current, set date to total days in that month if (totalDaysInNextMonth < d) { d = totalDaysInNextMonth; } // Check if newDate is in valid range if (newDate.getTime() < this.minTime) { newDate = this.minDate; } else if (newDate.getTime() > this.maxTime) { newDate = this.maxDate; } this.focused = newDate; focusedParsed = wpcdpk.getParsedDate(newDate); if (monthChanged && o.onChangeMonth) { o.onChangeMonth(focusedParsed.month, focusedParsed.year); } if (yearChanged && o.onChangeYear) { o.onChangeYear(focusedParsed.year); } if (decadeChanged && o.onChangeDecade) { o.onChangeDecade(this.curDecade); } }, _registerKey: function(key) { var exists = this.keys.some(function(curKey) { return curKey == key; }); if (!exists) { this.keys.push(key); } }, _unRegisterKey: function(key) { var index = this.keys.indexOf(key); this.keys.splice(index, 1); }, _isHotKeyPressed: function() { var currentHotKey, found = false, _this = this, pressedKeys = this.keys.sort(); for (var hotKey in hotKeys) { currentHotKey = hotKeys[hotKey]; if (pressedKeys.length != currentHotKey.length) { continue; } if (currentHotKey.every(function(key, i) { return key == pressedKeys[i]; })) { _this._trigger('hotKey', hotKey); found = true; } } return found; }, _trigger: function(event, args) { this.$el.trigger(event, args); }, _focusNextCell: function(keyCode, type) { type = type || this.cellType; var date = wpcdpk.getParsedDate(this._getFocusedDate()), y = date.year, m = date.month, d = date.date; if (this._isHotKeyPressed()) { return; } switch (keyCode) { case 37: // left type == 'day' ? ( d -= 1 ) : ''; type == 'month' ? ( m -= 1 ) : ''; type == 'year' ? ( y -= 1 ) : ''; break; case 38: // up type == 'day' ? ( d -= 7 ) : ''; type == 'month' ? ( m -= 3 ) : ''; type == 'year' ? ( y -= 4 ) : ''; break; case 39: // right type == 'day' ? ( d += 1 ) : ''; type == 'month' ? ( m += 1 ) : ''; type == 'year' ? ( y += 1 ) : ''; break; case 40: // down type == 'day' ? ( d += 7 ) : ''; type == 'month' ? ( m += 3 ) : ''; type == 'year' ? ( y += 4 ) : ''; break; } var nd = new Date(y, m, d); if (nd.getTime() < this.minTime) { nd = this.minDate; } else if (nd.getTime() > this.maxTime) { nd = this.maxDate; } this.focused = nd; }, _getFocusedDate: function() { var focused = this.focused || this.selectedDates[this.selectedDates.length - 1], d = this.parsedDate; if (!focused) { switch (this.view) { case 'days': focused = new Date(d.year, d.month, new Date().getDate()); break; case 'months': focused = new Date(d.year, d.month, 1); break; case 'years': focused = new Date(d.year, 0, 1); break; } } return focused; }, _getCell: function(date, type) { type = type || this.cellType; var d = wpcdpk.getParsedDate(date), selector = '.wpcdpk--cell[data-year="' + d.year + '"]', $cell; switch (type) { case 'month': selector = '[data-month="' + d.month + '"]'; break; case 'day': selector += '[data-month="' + d.month + '"][data-date="' + d.date + '"]'; break; } $cell = this.views[this.currentView].$el.find(selector); return $cell.length ? $cell : $(''); }, destroy: function() { var _this = this; _this.$el.off('.adp').data('wpcdpk', ''); _this.selectedDates = []; _this.focused = ''; _this.views = {}; _this.keys = []; _this.minRange = ''; _this.maxRange = ''; if (_this.opts.inline || !_this.elIsInput) { _this.$wpcdpk.closest('.wpcdpk-inline').remove(); } else { _this.$wpcdpk.remove(); } }, _handleAlreadySelectedDates: function( alreadySelected, selectedDate) { if (this.opts.range) { if (!this.opts.toggleSelected) { // Add possibility to select same date when range is true if (this.selectedDates.length != 2) { this._trigger('clickCell', selectedDate); } } else { this.removeDate(selectedDate); } } else if (this.opts.toggleSelected) { this.removeDate(selectedDate); } // Change last selected date to be able to change time when clicking on this cell if (!this.opts.toggleSelected) { this.lastSelectedDate = alreadySelected; if (this.opts.timepicker) { this.timepicker._setTime(alreadySelected); this.timepicker.update(); } } }, _onShowEvent: function(e) { if (!this.visible) { this.show(); } }, _onBlur: function() { if (!this.inFocus && this.visible) { this.hide(); } }, _onMouseDownWpcdpk: function(e) { this.inFocus = true; }, _onMouseUpWpcdpk: function(e) { this.inFocus = false; e.originalEvent.inFocus = true; if (!e.originalEvent.timepickerFocus) { this.$el.focus(); } }, _onKeyUpGeneral: function(e) { var val = this.$el.val(); if (!val) { this.clear(); } }, _onResize: function() { if (this.visible) { this.setPosition(); } }, _onMouseUpBody: function(e) { if (e.originalEvent.inFocus) { return; } if (this.visible && !this.inFocus) { this.hide(); } }, _onMouseUpEl: function(e) { e.originalEvent.inFocus = true; setTimeout(this._onKeyUpGeneral.bind(this), 4); }, _onKeyDown: function(e) { var code = e.which; this._registerKey(code); // Arrows if (code >= 37 && code <= 40) { e.preventDefault(); this._focusNextCell(code); } // Enter if (code == 13) { if (this.focused) { if (this._getCell(this.focused).hasClass('-disabled-')) { return; } if (this.view != this.opts.minView) { this.down(); } else { var alreadySelected = this._isSelected(this.focused, this.cellType); if (!alreadySelected) { if (this.timepicker) { this.focused.setHours(this.timepicker.hours); this.focused.setMinutes(this.timepicker.minutes); } this.selectDate(this.focused); return; } this._handleAlreadySelectedDates(alreadySelected, this.focused); } } } // Esc if (code == 27) { this.hide(); } }, _onKeyUp: function(e) { var code = e.which; this._unRegisterKey(code); }, _onHotKey: function(e, hotKey) { this._handleHotKey(hotKey); }, _onMouseEnterCell: function(e) { var $cell = $(e.target).closest('.wpcdpk--cell'), date = this._getDateFromCell($cell); // Prevent from unnecessary rendering and setting new currentDate this.silent = true; if (this.focused) { this.focused = ''; } $cell.addClass('-focus-'); this.focused = date; this.silent = false; if (this.opts.range && this.selectedDates.length == 1) { this.minRange = this.selectedDates[0]; this.maxRange = ''; if (wpcdpk.less(this.minRange, this.focused)) { this.maxRange = this.minRange; this.minRange = ''; } this.views[this.currentView]._update(); } }, _onMouseLeaveCell: function(e) { var $cell = $(e.target).closest('.wpcdpk--cell'); $cell.removeClass('-focus-'); this.silent = true; this.focused = ''; this.silent = false; }, _onTimeChange: function(e, h, m) { var date = new Date(), selectedDates = this.selectedDates, selected = false; if (selectedDates.length) { selected = true; date = this.lastSelectedDate; } date.setHours(h); date.setMinutes(m); if (!selected && !this._getCell(date).hasClass('-disabled-')) { this.selectDate(date); } else { this._setInputValue(); if (this.opts.onSelect) { this._triggerOnChange(); } } }, _onClickCell: function(e, date) { if (this.timepicker) { date.setHours(this.timepicker.hours); date.setMinutes(this.timepicker.minutes); } this.selectDate(date); }, set focused(val) { if (!val && this.focused) { var $cell = this._getCell(this.focused); if ($cell.length) { $cell.removeClass('-focus-'); } } this._focused = val; if (this.opts.range && this.selectedDates.length == 1) { this.minRange = this.selectedDates[0]; this.maxRange = ''; if (wpcdpk.less(this.minRange, this._focused)) { this.maxRange = this.minRange; this.minRange = ''; } } if (this.silent) { return; } this.date = val; }, get focused() { return this._focused; }, get parsedDate() { return wpcdpk.getParsedDate(this.date); }, set date(val) { if (!( val instanceof Date )) { return; } this.currentDate = val; if (this.inited && !this.silent) { this.views[this.view]._render(); this.nav._render(); if (this.visible && this.elIsInput) { this.setPosition(); } } return val; }, get date() { return this.currentDate; }, set view(val) { this.viewIndex = this.viewIndexes.indexOf(val); if (this.viewIndex < 0) { return; } this.prevView = this.currentView; this.currentView = val; if (this.inited) { if (!this.views[val]) { this.views[val] = new $.fn.wpcdpk.Body(this, val, this.opts); } else { this.views[val]._render(); } this.views[this.prevView].hide(); this.views[val].show(); this.nav._render(); if (this.opts.onChangeView) { this.opts.onChangeView(val); } if (this.elIsInput && this.visible) { this.setPosition(); } } return val; }, get view() { return this.currentView; }, get cellType() { return this.view.substring(0, this.view.length - 1); }, get minTime() { var min = wpcdpk.getParsedDate(this.minDate); return new Date(min.year, min.month, min.date).getTime(); }, get maxTime() { var max = wpcdpk.getParsedDate(this.maxDate); return new Date(max.year, max.month, max.date).getTime(); }, get curDecade() { return wpcdpk.getDecade(this.date); }, }; // Utils // ------------------------------------------------- wpcdpk.getDaysCount = function(date) { return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(); }; wpcdpk.getParsedDate = function(date) { return { year: date.getFullYear(), month: date.getMonth(), fullMonth: ( date.getMonth() + 1 ) < 10 ? '0' + ( date.getMonth() + 1 ) : date.getMonth() + 1, // One based date: date.getDate(), fullDate: date.getDate() < 10 ? '0' + date.getDate() : date.getDate(), day: date.getDay(), hours: date.getHours(), fullHours: date.getHours() < 10 ? '0' + date.getHours() : date.getHours(), minutes: date.getMinutes(), fullMinutes: date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(), }; }; wpcdpk.getDecade = function(date) { var firstYear = Math.floor(date.getFullYear() / 10) * 10; return [firstYear, firstYear + 9]; }; wpcdpk.template = function(str, data) { return str.replace(/#\{([\w]+)\}/g, function(source, match) { if (data[match] || data[match] === 0) { return data[match]; } }); }; wpcdpk.isSame = function(date1, date2, type) { if (!date1 || !date2) { return false; } var d1 = wpcdpk.getParsedDate(date1), d2 = wpcdpk.getParsedDate(date2), _type = type ? type : 'day', conditions = { day: d1.date == d2.date && d1.month == d2.month && d1.year == d2.year, month: d1.month == d2.month && d1.year == d2.year, year: d1.year == d2.year, }; return conditions[_type]; }; wpcdpk.less = function(dateCompareTo, date, type) { if (!dateCompareTo || !date) { return false; } return date.getTime() < dateCompareTo.getTime(); }; wpcdpk.bigger = function(dateCompareTo, date, type) { if (!dateCompareTo || !date) { return false; } return date.getTime() > dateCompareTo.getTime(); }; wpcdpk.getLeadingZeroNum = function(num) { return parseInt(num) < 10 ? '0' + num : num; }; /** * Returns copy of date with hours and minutes equals to 0 * @param date {Date} */ wpcdpk.resetTime = function(date) { if (typeof date != 'object') { return; } date = wpcdpk.getParsedDate(date); return new Date(date.year, date.month, date.date); }; $.fn.wpcdpk = function(options) { return this.each(function() { if (!$.data(this, pluginName)) { $.data(this, pluginName, new Wpcdpk(this, options)); } else { var _this = $.data(this, pluginName); _this.opts = $.extend(true, _this.opts, options); _this.update(); } }); }; $.fn.wpcdpk.Constructor = Wpcdpk; $.fn.wpcdpk.language = { en: { days: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], months: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ], monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ], today: 'Today', clear: 'Clear', dateFormat: 'mm/dd/yyyy', timeFormat: 'hh:ii aa', firstDay: 0, }, }; $(function() { $(autoInitSelector).wpcdpk(); }); } )(); ; ( function() { var templates = { days: '' + '
' + '
' + '
' + '
', months: '' + '
' + '
' + '
', years: '' + '
' + '
' + '
', }, wpcdpk = $.fn.wpcdpk, dp = wpcdpk.Constructor; wpcdpk.Body = function(d, type, opts) { this.d = d; this.type = type; this.opts = opts; this.$el = $(''); if (this.opts.onlyTimepicker) { return; } this.init(); }; wpcdpk.Body.prototype = { init: function() { this._buildBaseHtml(); this._render(); this._bindEvents(); }, _bindEvents: function() { this.$el.on('click', '.wpcdpk--cell', $.proxy(this._onClickCell, this)); }, _buildBaseHtml: function() { this.$el = $(templates[this.type]).appendTo(this.d.$content); this.$names = $('.wpcdpk--days-names', this.$el); this.$cells = $('.wpcdpk--cells', this.$el); }, _getDayNamesHtml: function(firstDay, curDay, html, i) { curDay = curDay != undefined ? curDay : firstDay; html = html ? html : ''; i = i != undefined ? i : 0; if (i > 7) { return html; } if (curDay == 7) { return this._getDayNamesHtml(firstDay, 0, html, ++i); } html += '
' + this.d.loc.daysMin[curDay] + '
'; return this._getDayNamesHtml(firstDay, ++curDay, html, ++i); }, _getCellContents: function(date, type) { var classes = 'wpcdpk--cell wpcdpk--cell-' + type, currentDate = new Date(), parent = this.d, minRange = dp.resetTime(parent.minRange), maxRange = dp.resetTime(parent.maxRange), opts = parent.opts, d = dp.getParsedDate(date), render = {}, html = d.date; switch (type) { case 'day': if (parent.isWeekend(d.day)) { classes += ' -weekend-'; } if (d.month != this.d.parsedDate.month) { classes += ' -other-month-'; if (!opts.selectOtherMonths) { classes += ' -disabled-'; } if (!opts.showOtherMonths) { html = ''; } } break; case 'month': html = parent.loc[parent.opts.monthsField][d.month]; break; case 'year': var decade = parent.curDecade; html = d.year; if (d.year < decade[0] || d.year > decade[1]) { classes += ' -other-decade-'; if (!opts.selectOtherYears) { classes += ' -disabled-'; } if (!opts.showOtherYears) { html = ''; } } break; } if (opts.onRenderCell) { render = opts.onRenderCell(date, type) || {}; html = render.html ? render.html : html; classes += render.classes ? ' ' + render.classes : ''; } if (opts.range) { if (dp.isSame(minRange, date, type)) { classes += ' -range-from-'; } if (dp.isSame(maxRange, date, type)) { classes += ' -range-to-'; } if (parent.selectedDates.length == 1 && parent.focused) { if ( ( dp.bigger(minRange, date) && dp.less(parent.focused, date) ) || ( dp.less(maxRange, date) && dp.bigger(parent.focused, date) )) { classes += ' -in-range-'; } if (dp.less(maxRange, date) && dp.isSame(parent.focused, date)) { classes += ' -range-from-'; } if (dp.bigger(minRange, date) && dp.isSame(parent.focused, date)) { classes += ' -range-to-'; } } else if (parent.selectedDates.length == 2) { if (dp.bigger(minRange, date) && dp.less(maxRange, date)) { classes += ' -in-range-'; } } } if (dp.isSame(currentDate, date, type)) { classes += ' -current-'; } if (parent.focused && dp.isSame(date, parent.focused, type)) { classes += ' -focus-'; } if (parent._isSelected(date, type)) { classes += ' -selected-'; } if (!parent._isInRange(date, type) || render.disabled) { classes += ' -disabled-'; } return { html: html, classes: classes, }; }, /** * Calculates days number to render. Generates days html and returns it. * @param {object} date - Date object * @returns {string} * @private */ _getDaysHtml: function(date) { var totalMonthDays = dp.getDaysCount(date), firstMonthDay = new Date(date.getFullYear(), date.getMonth(), 1).getDay(), lastMonthDay = new Date(date.getFullYear(), date.getMonth(), totalMonthDays).getDay(), daysFromPevMonth = firstMonthDay - this.d.loc.firstDay, daysFromNextMonth = 6 - lastMonthDay + this.d.loc.firstDay; daysFromPevMonth = daysFromPevMonth < 0 ? daysFromPevMonth + 7 : daysFromPevMonth; daysFromNextMonth = daysFromNextMonth > 6 ? daysFromNextMonth - 7 : daysFromNextMonth; var startDayIndex = -daysFromPevMonth + 1, m, y, html = ''; for (var i = startDayIndex, max = totalMonthDays + daysFromNextMonth; i <= max; i++) { y = date.getFullYear(); m = date.getMonth(); html += this._getDayHtml(new Date(y, m, i)); } return html; }, _getDayHtml: function(date) { var content = this._getCellContents(date, 'day'); return '
' + content.html + '
'; }, /** * Generates months html * @param {object} date - date instance * @returns {string} * @private */ _getMonthsHtml: function(date) { var html = '', d = dp.getParsedDate(date), i = 0; while (i < 12) { html += this._getMonthHtml(new Date(d.year, i)); i++; } return html; }, _getMonthHtml: function(date) { var content = this._getCellContents(date, 'month'); return '
' + content.html + '
'; }, _getYearsHtml: function(date) { var d = dp.getParsedDate(date), decade = dp.getDecade(date), firstYear = decade[0] - 1, html = '', i = firstYear; for (i; i <= decade[1] + 1; i++) { html += this._getYearHtml(new Date(i, 0)); } return html; }, _getYearHtml: function(date) { var content = this._getCellContents(date, 'year'); return '
' + content.html + '
'; }, _renderTypes: { days: function() { var dayNames = this._getDayNamesHtml(this.d.loc.firstDay), days = this._getDaysHtml(this.d.currentDate); this.$cells.html(days); this.$names.html(dayNames); }, months: function() { var html = this._getMonthsHtml(this.d.currentDate); this.$cells.html(html); }, years: function() { var html = this._getYearsHtml(this.d.currentDate); this.$cells.html(html); }, }, _render: function() { if (this.opts.onlyTimepicker) { return; } this._renderTypes[this.type].bind(this)(); }, _update: function() { var $cells = $('.wpcdpk--cell', this.$cells), _this = this, classes, $cell, date; $cells.each(function(cell, i) { $cell = $(this); date = _this.d._getDateFromCell($(this)); classes = _this._getCellContents(date, _this.d.cellType); $cell.attr('class', classes.classes); }); }, show: function() { if (this.opts.onlyTimepicker) { return; } this.$el.addClass('active'); this.acitve = true; }, hide: function() { this.$el.removeClass('active'); this.active = false; }, // Events // ------------------------------------------------- _handleClick: function(el) { var date = el.data('date') || 1, month = el.data('month') || 0, year = el.data('year') || this.d.parsedDate.year, dp = this.d; // Change view if min view does not reach yet if (dp.view != this.opts.minView) { dp.down(new Date(year, month, date)); return; } // Select date if min view is reached var selectedDate = new Date(year, month, date), alreadySelected = this.d._isSelected(selectedDate, this.d.cellType); if (!alreadySelected) { dp._trigger('clickCell', selectedDate); return; } dp._handleAlreadySelectedDates.bind(dp, alreadySelected, selectedDate)(); }, _onClickCell: function(e) { var $el = $(e.target).closest('.wpcdpk--cell'); if ($el.hasClass('-disabled-')) { return; } this._handleClick.bind(this)($el); }, }; } )(); ; ( function() { var template = '' + '
#{prevHtml}
' + '
#{title}
' + '
#{nextHtml}
', buttonsContainerTemplate = '
', button = '#{label}', wpcdpk = $.fn.wpcdpk, dp = wpcdpk.Constructor; wpcdpk.Navigation = function(d, opts) { this.d = d; this.opts = opts; this.$buttonsContainer = ''; this.init(); }; wpcdpk.Navigation.prototype = { init: function() { this._buildBaseHtml(); this._bindEvents(); }, _bindEvents: function() { this.d.$nav.on('click', '.wpcdpk--nav-action', $.proxy(this._onClickNavButton, this)); this.d.$nav.on('click', '.wpcdpk--nav-title', $.proxy(this._onClickNavTitle, this)); this.d.$wpcdpk.on('click', '.wpcdpk--button', $.proxy(this._onClickNavButton, this)); }, _buildBaseHtml: function() { if (!this.opts.onlyTimepicker) { this._render(); } this._addButtonsIfNeed(); }, _addButtonsIfNeed: function() { if (this.opts.todayButton) { this._addButton('today'); } if (this.opts.clearButton) { this._addButton('clear'); } }, _render: function() { var title = this._getTitle(this.d.currentDate), html = dp.template(template, $.extend({title: title}, this.opts)); this.d.$nav.html(html); if (this.d.view == 'years') { $('.wpcdpk--nav-title', this.d.$nav).addClass('-disabled-'); } this.setNavStatus(); }, _getTitle: function(date) { return this.d.formatDate(this.opts.navTitles[this.d.view], date); }, _addButton: function(type) { if (!this.$buttonsContainer.length) { this._addButtonsContainer(); } var data = { action: type, label: this.d.loc[type], }, html = dp.template(button, data); if ($('[data-action=' + type + ']', this.$buttonsContainer).length) { return; } this.$buttonsContainer.append(html); }, _addButtonsContainer: function() { this.d.$wpcdpk.append(buttonsContainerTemplate); this.$buttonsContainer = $('.wpcdpk--buttons', this.d.$wpcdpk); }, setNavStatus: function() { if (!( this.opts.minDate || this.opts.maxDate ) || !this.opts.disableNavWhenOutOfRange) { return; } var date = this.d.parsedDate, m = date.month, y = date.year, d = date.date; switch (this.d.view) { case 'days': if (!this.d._isInRange(new Date(y, m - 1, 1), 'month')) { this._disableNav('prev'); } if (!this.d._isInRange(new Date(y, m + 1, 1), 'month')) { this._disableNav('next'); } break; case 'months': if (!this.d._isInRange(new Date(y - 1, m, d), 'year')) { this._disableNav('prev'); } if (!this.d._isInRange(new Date(y + 1, m, d), 'year')) { this._disableNav('next'); } break; case 'years': var decade = dp.getDecade(this.d.date); if (!this.d._isInRange(new Date(decade[0] - 1, 0, 1), 'year')) { this._disableNav('prev'); } if (!this.d._isInRange(new Date(decade[1] + 1, 0, 1), 'year')) { this._disableNav('next'); } break; } }, _disableNav: function(nav) { $('[data-action="' + nav + '"]', this.d.$nav). addClass('-disabled-'); }, _activateNav: function(nav) { $('[data-action="' + nav + '"]', this.d.$nav). removeClass('-disabled-'); }, _onClickNavButton: function(e) { var $el = $(e.target).closest('[data-action]'), action = $el.data('action'); this.d[action](); }, _onClickNavTitle: function(e) { if ($(e.target).hasClass('-disabled-')) { return; } if (this.d.view == 'days') { return this.d.view = 'months'; } this.d.view = 'years'; }, }; } )(); ; ( function() { var template = '
' + '
' + ' #{hourVisible}' + ' :' + ' #{minValue}' + '
' + '
' + '
' + ' ' + '
' + '
' + ' ' + '
' + '
' + '
', wpcdpk = $.fn.wpcdpk, dp = wpcdpk.Constructor; wpcdpk.Timepicker = function(inst, opts) { this.d = inst; this.opts = opts; this.init(); }; wpcdpk.Timepicker.prototype = { init: function() { var input = 'input'; this._setTime(this.d.date); this._buildHTML(); if (navigator.userAgent.match(/trident/gi)) { input = 'change'; } this.d.$el.on('selectDate', this._onSelectDate.bind(this)); this.$ranges.on(input, this._onChangeRange.bind(this)); this.$ranges.on('mouseup', this._onMouseUpRange.bind(this)); this.$ranges.on('mousemove focus ', this._onMouseEnterRange.bind(this)); this.$ranges.on('mouseout blur', this._onMouseOutRange.bind(this)); }, _setTime: function(date) { var _date = dp.getParsedDate(date); this._handleDate(date); this.hours = _date.hours < this.minHours ? this.minHours : _date.hours; this.minutes = _date.minutes < this.minMinutes ? this.minMinutes : _date.minutes; }, /** * Sets minHours and minMinutes from date (usually it's a minDate) * Also changes minMinutes if current hours are bigger then @date hours * @param date {Date} * @private */ _setMinTimeFromDate: function(date) { this.minHours = date.getHours(); this.minMinutes = date.getMinutes(); // If, for example, min hours are 10, and current hours are 12, // update minMinutes to default value, to be able to choose whole range of values if (this.d.lastSelectedDate) { if (this.d.lastSelectedDate.getHours() > date.getHours()) { this.minMinutes = this.opts.minMinutes; } } }, _setMaxTimeFromDate: function(date) { this.maxHours = date.getHours(); this.maxMinutes = date.getMinutes(); if (this.d.lastSelectedDate) { if (this.d.lastSelectedDate.getHours() < date.getHours()) { this.maxMinutes = this.opts.maxMinutes; } } }, _setDefaultMinMaxTime: function() { var maxHours = 23, maxMinutes = 59, opts = this.opts; this.minHours = opts.minHours < 0 || opts.minHours > maxHours ? 0 : opts.minHours; this.minMinutes = opts.minMinutes < 0 || opts.minMinutes > maxMinutes ? 0 : opts.minMinutes; this.maxHours = opts.maxHours < 0 || opts.maxHours > maxHours ? maxHours : opts.maxHours; this.maxMinutes = opts.maxMinutes < 0 || opts.maxMinutes > maxMinutes ? maxMinutes : opts.maxMinutes; }, /** * Looks for min/max hours/minutes and if current values * are out of range sets valid values. * @private */ _validateHoursMinutes: function(date) { if (this.hours < this.minHours) { this.hours = this.minHours; } else if (this.hours > this.maxHours) { this.hours = this.maxHours; } if (this.minutes < this.minMinutes) { this.minutes = this.minMinutes; } else if (this.minutes > this.maxMinutes) { this.minutes = this.maxMinutes; } }, _buildHTML: function() { var lz = dp.getLeadingZeroNum, data = { hourMin: this.minHours, hourMax: lz(this.maxHours), hourStep: this.opts.hoursStep, hourValue: this.hours, hourVisible: lz(this.displayHours), minMin: this.minMinutes, minMax: lz(this.maxMinutes), minStep: this.opts.minutesStep, minValue: lz(this.minutes), }, _template = dp.template(template, data); this.$timepicker = $(_template).appendTo(this.d.$wpcdpk); this.$ranges = $('[type="range"]', this.$timepicker); this.$hours = $('[name="hours"]', this.$timepicker); this.$minutes = $('[name="minutes"]', this.$timepicker); this.$hoursText = $('.wpcdpk--time-current-hours', this.$timepicker); this.$minutesText = $('.wpcdpk--time-current-minutes', this.$timepicker); if (this.d.ampm) { this.$ampm = $(''). appendTo($('.wpcdpk--time-current', this.$timepicker)). html(this.dayPeriod); this.$timepicker.addClass('-am-pm-'); } }, _updateCurrentTime: function() { var h = dp.getLeadingZeroNum(this.displayHours), m = dp.getLeadingZeroNum(this.minutes); this.$hoursText.html(h); this.$minutesText.html(m); if (this.d.ampm) { this.$ampm.html(this.dayPeriod); } }, _updateRanges: function() { this.$hours.attr({ min: this.minHours, max: this.maxHours, }).val(this.hours); this.$minutes.attr({ min: this.minMinutes, max: this.maxMinutes, }).val(this.minutes); }, /** * Sets minHours, minMinutes etc. from date. If date is not passed, than sets * values from options * @param [date] {object} - Date object, to get values from * @private */ _handleDate: function(date) { this._setDefaultMinMaxTime(); if (date) { if (dp.isSame(date, this.d.opts.minDate)) { this._setMinTimeFromDate(this.d.opts.minDate); } else if (dp.isSame(date, this.d.opts.maxDate)) { this._setMaxTimeFromDate(this.d.opts.maxDate); } } this._validateHoursMinutes(date); }, update: function() { this._updateRanges(); this._updateCurrentTime(); }, /** * Calculates valid hour value to display in text input and wpcdpk's body. * @param date {Date|Number} - date or hours * @param [ampm] {Boolean} - 12 hours mode * @returns {{hours: *, dayPeriod: string}} * @private */ _getValidHoursFromDate: function(date, ampm) { var d = date, hours = date; if (date instanceof Date) { d = dp.getParsedDate(date); hours = d.hours; } var _ampm = ampm || this.d.ampm, dayPeriod = 'am'; if (_ampm) { switch (true) { case hours == 0: hours = 12; break; case hours == 12: dayPeriod = 'pm'; break; case hours > 11: hours = hours - 12; dayPeriod = 'pm'; break; default: break; } } return { hours: hours, dayPeriod: dayPeriod, }; }, set hours(val) { this._hours = val; var displayHours = this._getValidHoursFromDate(val); this.displayHours = displayHours.hours; this.dayPeriod = displayHours.dayPeriod; }, get hours() { return this._hours; }, // Events // ------------------------------------------------- _onChangeRange: function(e) { var $target = $(e.target), name = $target.attr('name'); this.d.timepickerIsActive = true; this[name] = $target.val(); this._updateCurrentTime(); this.d._trigger('timeChange', [this.hours, this.minutes]); this._handleDate(this.d.lastSelectedDate); this.update(); }, _onSelectDate: function(e, data) { this._handleDate(data); this.update(); }, _onMouseEnterRange: function(e) { var name = $(e.target).attr('name'); $('.wpcdpk--time-current-' + name, this.$timepicker). addClass('-focus-'); }, _onMouseOutRange: function(e) { var name = $(e.target).attr('name'); if (this.d.inFocus) { return; } // Prevent removing focus when mouse out of range slider $('.wpcdpk--time-current-' + name, this.$timepicker). removeClass('-focus-'); }, _onMouseUpRange: function(e) { this.d.timepickerIsActive = false; }, }; } )(); } )(window, jQuery);